package com.example.demo.service.impl;

import com.example.demo.entity.Coupon;
import com.example.demo.exception.BusinessException;
import com.example.demo.exception.ErrorCode;
import com.example.demo.mapper.CouponMapper;
import com.example.demo.service.CouponService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class CouponServiceImpl implements CouponService {

    @Autowired
    private CouponMapper couponMapper;

    @Override
    public Coupon createCoupon(Coupon coupon) {
        // Check if coupon with same name already exists
        Coupon existingCoupon = couponMapper.selectCouponByName(coupon.getName());
        if (existingCoupon != null) {
            log.warn("Coupon already exists: {}", coupon.getName());
            throw new BusinessException(ErrorCode.COUPON_EXISTS);
        }

        // Set creation and update timestamps
        Date now = new Date();
        coupon.setCreate_time(now);
        coupon.setUpdate_time(now);

        // Insert new coupon
        couponMapper.insertCoupon(coupon);
        log.info("Created new coupon: id={}, name={}", coupon.getId(), coupon.getName());
        
        return coupon;
    }

    @Override
    public Coupon getCouponById(Integer id) {
        if (id == null) {
            log.warn("Attempt to get coupon with null id");
            throw new BusinessException(ErrorCode.INVALID_PARAMETER);
        }
        
        Coupon coupon = couponMapper.selectCouponById(id);
        if (coupon == null) {
            log.warn("Coupon not found: id={}", id);
            throw new BusinessException(ErrorCode.COUPON_NOT_FOUND);
        }
        return coupon;
    }

    @Override
    public Coupon getCouponByName(String name) {
        if (name == null || name.isEmpty()) {
            log.warn("Attempt to get coupon with empty name");
            throw new BusinessException(ErrorCode.INVALID_PARAMETER);
        }
        
        Coupon coupon = couponMapper.selectCouponByName(name);
        if (coupon == null) {
            log.warn("Coupon not found: name={}", name);
            throw new BusinessException(ErrorCode.COUPON_NOT_FOUND);
        }
        return coupon;
    }

    @Override
    public boolean updateCoupon(Coupon coupon) {
        if (coupon == null || coupon.getId() == null) {
            log.warn("Attempt to update invalid coupon");
            throw new BusinessException(ErrorCode.CREATE_COUPON_FAILED);
        }
        
        // Verify coupon exists
        Coupon existingCoupon = getCouponById(coupon.getId());
        if (existingCoupon == null) {
            log.warn("Coupon not found for update: id={}", coupon.getId());
            throw new BusinessException(ErrorCode.INVALID_PARAMETER);
        }
        
        // Set update timestamp
        coupon.setUpdate_time(new Date());
        
        int rowsUpdated = couponMapper.updateCoupon(coupon);
        if (rowsUpdated == 0) {
            log.error("Failed to update coupon: id={}", coupon.getId());
            throw new BusinessException(ErrorCode.UPDATE_COUPON_FAILED);
        }
        
        log.info("Updated coupon: id={}", coupon.getId());
        return true;
    }

    @Override
    public boolean updateCouponStatus(Integer id, Integer status) {
        if (id == null || status == null) {
            log.warn("Attempt to update coupon status with invalid parameters");
            throw new BusinessException(ErrorCode.INVALID_PARAMETER);
        }
        
        // Verify coupon exists
        Coupon existingCoupon = getCouponById(id);
        if (existingCoupon == null) {
            log.warn("Coupon not found for status update: id={}", id);
            throw new BusinessException(ErrorCode.COUPON_NOT_FOUND);
        }
    
        
        int rowsUpdated = couponMapper.updateCouponStatus(id, status);
        if (rowsUpdated == 0) {
            log.error("Failed to update coupon status: id={}", id);
            throw new BusinessException(ErrorCode.UPDATE_COUPON_FAILED);
        }
        
        log.info("Updated coupon status: id={}, status={}", id, status);
        return true;
    }

    @Override
    public Map<String, Object> getCouponList(Integer page, Integer limit, String keyword) {
        if (page == null || limit == null) {
            log.warn("Invalid pagination parameters: page={}, limit={}", page, limit);
            throw new BusinessException(ErrorCode.INVALID_PARAMETER);
        }

        // Start pagination
        PageHelper.startPage(page, limit);
        
        // Query coupons with optional keyword filter
        List<Coupon> coupons;
        coupons = couponMapper.selectCouponsByKeyword(keyword);
        
        // Get total count
        PageInfo<Coupon> pageInfo = new PageInfo<>(coupons);
        
        // Build result map
        Map<String, Object> result = new HashMap<>();
        result.put("list", coupons);
        result.put("totalCount", pageInfo.getTotal());
        
        log.info("Fetched {} coupons on page {}", coupons.size(), page);
        return result;
    }

    @Override
    public boolean deleteCoupon(Integer id) {
        if (id == null) {
            log.warn("Attempt to delete coupon with null id");
            throw new BusinessException(ErrorCode.INVALID_PARAMETER);
        }

        // Verify coupon exists
        Coupon existingCoupon = getCouponById(id);
        if (existingCoupon == null) {
            log.warn("Coupon not found for deletion: id={}", id);
            throw new BusinessException(ErrorCode.COUPON_NOT_FOUND);
        }

        int rowsDeleted = couponMapper.deleteCoupon(id);
        if (rowsDeleted == 0) {
            log.error("Failed to delete coupon: id={}", id);
            throw new BusinessException(ErrorCode.DELETE_COUPON_FAILED);
        }

        log.info("Deleted coupon: id={}", id);
        return true;
    }
}
